package com.autonavi.yunda.yunji.core.service;

import com.autonavi.yunda.yunji.common.exception.AmapPreconditions;
import com.autonavi.yunda.yunji.core.enums.DatasourceType;
import com.autonavi.yunda.yunji.core.model.condition.DatasourceQueryCondition;
import com.autonavi.yunda.yunji.core.model.dto.DatasourceConfigDTO;
import com.autonavi.yunda.yunji.core.model.mappers.DatasourceConfigMapper;
import com.autonavi.yunda.yunji.core.vo.response.DataSourcePageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

/**
 * @author sunzhenbang
 */
@Repository
public class DatasourceConfigService {
    @Resource
    private DatasourceConfigMapper datasourceConfigMapper;

    public List<Long> selectIds() {
        return datasourceConfigMapper.selectIds();
    }

    public Long add(DatasourceConfigDTO datasourceConfigDTO) {
        datasourceConfigMapper.insert(datasourceConfigDTO);
        return datasourceConfigDTO.getId();
    }

    public DatasourceConfigDTO findByIdOrThrow(Long id) {
        QueryWrapper<DatasourceConfigDTO> wrapper = new QueryWrapper<>();
        wrapper.eq("id", id);
        wrapper.eq("is_deleted", "0");
        DatasourceConfigDTO dto = datasourceConfigMapper.selectOne(wrapper);
        AmapPreconditions.checkArgumentForUser(dto != null, "不存在该数据源信息 id = " + id);
        return dto;
    }

    public void checkDbNameOrThrow(String dbName) {
        QueryWrapper<DatasourceConfigDTO> wrapper = new QueryWrapper<>();
        wrapper.eq("dbname", dbName);
        AmapPreconditions.checkArgumentForUser(datasourceConfigMapper.selectOne(wrapper) == null, "该dbname已存在 dbName = " + dbName);
    }

    public void update(DatasourceConfigDTO datasourceConfigDTO) {
        datasourceConfigMapper.updateById(datasourceConfigDTO);
    }

    public DataSourcePageVO listByCondition(DatasourceQueryCondition condition) {
        if (condition.ids.isEmpty()) {
            return new DataSourcePageVO(List.of(), 0);
        }
        Page<DatasourceConfigDTO> page = new Page<>(condition.getPageNo(), condition.getPageSize());
        datasourceConfigMapper.selectPage(page, getDataSourceWrapper(condition));
        return new DataSourcePageVO(page.getRecords(), page.getTotal());
    }

    private QueryWrapper<DatasourceConfigDTO> getDataSourceWrapper(DatasourceQueryCondition condition) {
        QueryWrapper<DatasourceConfigDTO> wrapper = new QueryWrapper<>();
        if (null != condition.type) {
            wrapper.like("type", condition.type);
        }
        if (!CollectionUtils.isEmpty(condition.typeList)) {
            wrapper.in("type", condition.typeList);
        }
        if (StringUtils.isNotBlank(condition.dbname)) {
            wrapper.like("dbname", condition.dbname);
        }
        if (StringUtils.isNotBlank(condition.config)) {
            wrapper.like("config", condition.config);
        }
        if (StringUtils.isNotBlank(condition.description)) {
            wrapper.like("description", condition.description);
        }
        if (!CollectionUtils.isEmpty(condition.ids)) {
            wrapper.in("id", condition.ids);
        }
        wrapper.orderByDesc("id");
        wrapper.eq("is_deleted", 0);
        return wrapper;
    }

    public List<DatasourceConfigDTO> selectList(Collection<DatasourceType> datasourceTypes, List<String> ids) {
        QueryWrapper<DatasourceConfigDTO> wrapper = new QueryWrapper<>();
        if (ids != null && !ids.isEmpty()) {
            wrapper.in("id", ids);
        }
        wrapper.in("type", datasourceTypes);
        wrapper.eq("is_deleted", 0);
        return datasourceConfigMapper.selectList(wrapper);
    }

    public DatasourceConfigDTO selectOneByDbName(String dbname) {
        QueryWrapper<DatasourceConfigDTO> wrapper = new QueryWrapper<>();
        wrapper.eq("is_deleted", 0);
        wrapper.eq("dbname", dbname);
        return datasourceConfigMapper.selectOne(wrapper);
    }
}
